# 1.添加cmake版本说明
cmake_minimum_required(VERSION 3.5)

# 全局设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 2.声明工程名称
project(user_server)

find_package(OpenSSL REQUIRED)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

set(target "user_server")
set(test_client "user_client")

# 3.检测并生成proto框架代码
# 3.1 添加所需的proto映射代码文件名称
set(proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../proto)
set(proto_files base.proto user.proto file.proto)
# 3.2 检测框架代码文件是否已经生成
set(proto_h "")
set(proto_cc "")
set(proto_srcs "")
foreach(proto_file ${proto_files})
    # 3.3 如果没有生成，则预定义生成指令 ———— 用于构建项目之前先生成框架代码
    string(REPLACE ".proto" ".pb.cc" proto_cc ${proto_file})
    string(REPLACE ".proto" ".pb.h" proto_h ${proto_file})
    if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}${proto_cc})
        add_custom_command(
            PRE_BUILD 
            COMMAND protoc
            ARGS --cpp_out=${CMAKE_CURRENT_BINARY_DIR} -I ${proto_path} --experimental_allow_proto3_optional ${proto_path}/${proto_file}
            DEPENDS ${proto_path}/${proto_file}
            OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc}
            COMMENT "生成protobuf框架代码文件: ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc}"
        )
    endif()
    # 3.4 将所有的框架源码文件名称保存起来
    list(APPEND proto_srcs ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc})    
endforeach()

# 3.检测并生成ODB框架代码
# 3.1 添加所需的odb映射代码文件名称
set(odb_path ${CMAKE_CURRENT_SOURCE_DIR}/../odb)
set(odb_files user.hxx outbox_event.hxx)
# 3.2 检测框架代码文件是否已经生成
set(odb_hxx "")
set(odb_cxx "")
set(odb_srcs "")
foreach(odb_file ${odb_files})
    # 3.3 如果没有生成，则预定义生成指令 ———— 用于构建项目之前先生成框架代码
    string(REPLACE ".hxx" "-odb.hxx" odb_hxx ${odb_file})
    string(REPLACE ".hxx" "-odb.cxx" odb_cxx ${odb_file})
    if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${odb_cxx})
        add_custom_command(
            PRE_BUILD 
            COMMAND odb
            ARGS -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time ${odb_path}/${odb_file}
            DEPENDS ${odb_path}/${odb_file}
            OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${odb_cxx} ${CMAKE_CURRENT_BINARY_DIR}/${odb_hxx}
            COMMENT "生成ODB框架代码文件: ${CMAKE_CURRENT_BINARY_DIR}/${odb_cxx}"
        )
    endif()
    # 3.4 将所有的框架源码文件名称保存起来
    list(APPEND odb_srcs ${CMAKE_CURRENT_BINARY_DIR}/${odb_cxx})    
endforeach()

# 4.获取源码目录下的所有源码文件
set(src_files "")
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source src_files)
set(test_files "")
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/test test_files)
set(outbox_unit_test ${CMAKE_CURRENT_SOURCE_DIR}/test/outbox_table_test.cc)
set(sync_worker_test ${CMAKE_CURRENT_SOURCE_DIR}/test/sync_worker_test.cc)
set(cache_service_test ${CMAKE_CURRENT_SOURCE_DIR}/test/cache_service_test.cc)
list(REMOVE_ITEM test_files ${outbox_unit_test})
list(REMOVE_ITEM test_files ${sync_worker_test})
list(REMOVE_ITEM test_files ${cache_service_test})

# 5.声明目标及依赖
add_executable(${target} ${src_files} ${proto_srcs} ${odb_srcs})
add_executable(${test_client} ${test_files} ${proto_srcs} ${odb_srcs})
add_executable(outbox_table_test ${outbox_unit_test} ${proto_srcs} ${odb_srcs})
add_executable(sync_worker_test ${sync_worker_test} ${proto_srcs} ${odb_srcs})
add_executable(cache_service_test ${cache_service_test} ${proto_srcs} ${odb_srcs})

# 6.设置头文件默认搜索路径
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../odb)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../third/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

# 7.设置需要连接的库
target_link_libraries(${target} -lgflags -lgtest -lspdlog -lfmt -lbrpc -lleveldb -lprotobuf -letcd-cpp-api -lcpprest -ljsoncpp -lcurl -lodb-mysql -lodb -lodb-boost -lcpr -lelasticlient -lhiredis -lredis++ OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(${test_client} -lgflags -lspdlog -lgtest -lfmt -lbrpc -lleveldb -lprotobuf -letcd-cpp-api -lcpprest -ljsoncpp -lcurl -lodb-mysql -lodb -lodb-boost -lcpr -lelasticlient -lhiredis -lredis++ OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(outbox_table_test -lgflags -lspdlog -lgtest -lfmt -lbrpc -lleveldb -lprotobuf -letcd-cpp-api -lcpprest -ljsoncpp -lcurl -lodb-mysql -lodb -lodb-boost -lcpr -lelasticlient -lhiredis -lredis++ OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(sync_worker_test -lgflags -lspdlog -lgtest -lfmt -lbrpc -lleveldb -lprotobuf -letcd-cpp-api -lcpprest -ljsoncpp -lcurl -lodb-mysql -lodb -lodb-boost -lcpr -lelasticlient -lhiredis -lredis++ OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(cache_service_test -lgflags -lspdlog -lgtest -lfmt -lbrpc -lleveldb -lprotobuf -letcd-cpp-api -lcpprest -ljsoncpp -lcurl -lodb-mysql -lodb -lodb-boost -lcpr -lelasticlient -lhiredis -lredis++ OpenSSL::SSL OpenSSL::Crypto)

# 8.设置安装路径
INSTALL(TARGETS ${target} ${test_client} RUNTIME DESTINATION bin)
